#!/usr/bin/perl -w

package perlmod::analyser;

use GD;

use Data::Dumper;

sub new {
	
	#grab my passed perameters
	my ( $class , $filename ) = @_;
	
	#create my object
	my $self = {};
	
	#populate it
	$self->{'filename'} = $filename;
	
	#now load intoit
	$self->{'gd'} = GD::Image->new($filename);
	
	#and keep everything updated
	( $self->{'width'} , $self->{'height'} ) = $self->{'gd'}->getBounds();
	
	#return a blessed reference
	return bless($self,$class);
	
}


sub extractpixels {
	
	#grab my passed perameters
	my ( $self ) = @_;
	
	#create some temporary storage
	my @pixelindex;
	my $height = $self->{'height'};
	my $width = $self->{'width'};
	my $gd = $self->{'gd'};
	
	foreach $y ( 0..$height ) {
		
		foreach $x ( 0..$width ) {
			
			$pixelindex[$gd->getPixel($x,$y)]++;
			
		}
		
	}
	
	#now clear out any blanks
	foreach $i ( 0..@pixelindex-1) {
		
		$pixelindex[$i] = defined($pixelindex[$i]) ? $pixelindex[$i] : 0;
		
	}
	
	#and now store it
	$self->{'pixelindex'} = \@pixelindex;
	
}



sub extractclut {
	
	#get my passed perameters
	my ( $self ) = @_;
	
	#set up some storage
	my @clut;
	my $gd = $self->{'gd'};
	my $clutmax = $gd->colorsTotal();
	
	foreach $i ( 0..$clutmax ) {
		
		push(@clut,[$gd->rgb($i)]);
		
	}
	
	#and store it
	$self->{'clut'} = \@clut;
	$self->{'clutmax'} = $clutmax;
	
}





#check clut for clipping
sub clutclipcheck {
	
	#get my passed parameters
	my ( $self , $threshold ) = @_;
	
	#get my clut
	my @clut = @{ $self->{'clut'} };
	
	#set up some storage
	my %clipping;
	$clipping{'red'} = [];
	$clipping{'green'} = [];
	$clipping{'blue'} = [];
	$clipping{'all'} = [];
	$clipping{'avg'} = [];
	
	#now spin through the clut and check if it's clipped
	foreach $i ( 0..@clut-1 ) {
		
		#get our colour
		my @colour = @{ $clut[$i] };
		
		#check red channel
		if ( $colour[0] >= $threshold ) {
			
			#red channel is clipped
			push( @{ $clipping{'red'} } , $i );
			
		}
		
		#check green channel
		if ( $colour[1] >= $threshold ) {
			
			#green channel is clipped
			push( @{ $clipping{'green'} } , $i );
			
		}
		
		#check blue channels
		if ( $colour[2] >= $threshold ) {
			
			#blue chanelis clipped
			push( @{ $clipping{'blue'} } , $i );
			
		}
		
		#check all at once
		if ( ( $colour[0] >= $threshold ) && ( $colour[1] >= $threshold ) && ( $colour[2] >= $threshold ) ) {
			
			#all channels clipped
			push( @{ $clipping{'all'} } , $i );
			
		}
		
		#check average value
		if ( ( $colour[0] + $colour[1] + $colour[2] ) / 3 >= $threshold ) {
			
			#average brightness clipped
			push( @{ $clipping{'avg'} } , $i );
			
		}
		
	}
	
	
	#and store it
	$self->{'clutclipping'} = \%clipping;
	
}



#check the pixels for the clipping counts
sub pixelclipcheck {
	
	#get my passed perameters
	my ( $self ) = @_;
	
	#get my clut clipping index
	my %clutclipping = %{ $self->{'clutclipping'} };
	
	#and get my pixel index
	my @pixelindex = @{ $self->{'pixelindex'} };
	
	#and create a new pixel clipping index
	my %pixelclipping;
	
	#now loop through it
	
	#for each channel
	foreach $channel ( "red" , "green" , "blue" , "all" , "avg" ) {
		
		#reset the count for this channel
		$pixelclipping{$channel} = 0;
		
		#for each clut index that is clipped
		foreach $clutindex ( @{ $clutclipping{$channel} } ) {
			
			#add this pixel count to the total
			$pixelclipping{$channel} += $pixelindex[$clutindex] ? $pixelindex[$clutindex] : 0;
		}
		
	}
	
	#now store it permanently
	$self->{'pixelclipping'} = \%pixelclipping;
	
}





#check for the average pixel brightness
sub avgcheck {
	
	my ( $self ) = @_;
	
	#get my pixel index
	my @pixelindex = @{ $self->{'pixelindex'} };
	
	#get my clut
	my @clut = @{ $self->{'clut'} };
	
	#create some storage
	my %avg;
	$avg{'red'} = 0;
	$avg{'green'} = 0;
	$avg{'blue'} = 0;
	$avg{'all'} = 0;
	$avg{'avg'} = 0;
	
	$avg{'totalred'} = 0;
	$avg{'totalgreen'} = 0;
	$avg{'totalblue'} = 0;
	$avg{'totalall'} = 0;
	$avg{'totalavg'} = 0;
	
	#for each index entry
	foreach $clutindex ( 1..@pixelindex-1 ) {
		
		#get my colour
		@colour = @{ $clut[$clutindex] };
		
		#add it to each channel as required
		
		#red
		$avg{'totalred'} += ( $colour[0] * $pixelindex[$clutindex] );
		
		#green
		$avg{'totalgreen'} += ( $colour[1] * $pixelindex[$clutindex] );
		
		#blue
		$avg{'totalblue'} += ( $colour[2] * $pixelindex[$clutindex] );
		
		#all
		$avg{'totalall'} += ( $colour[0] * $pixelindex[$clutindex] );
		$avg{'totalall'} += ( $colour[1] * $pixelindex[$clutindex] );
		$avg{'totalall'} += ( $colour[2] * $pixelindex[$clutindex] );
		
		#avg
		$avg{'totalavg'} += ( ( ( $colour[0] + $colour[1] + $colour[2] ) / 3 ) * $pixelindex[$clutindex] );
		
	}
	
	
	#now get our total pixels
	my $pixelcount = ( $self->{'width'} * $self->{'height'} );
	
	#and close out the averages
	$avg{'red'} = int( $avg{'totalred'} / $pixelcount );
	$avg{'green'} = int( $avg{'totalgreen'} / $pixelcount );
	$avg{'blue'} = int( $avg{'totalblue'} / $pixelcount );
	$avg{'all'} = int( $avg{'totalall'} / ( $pixelcount * 3 ) );
	$avg{'avg'} = int( $avg{'totalavg'} / $pixelcount );
	
	#and now store it
	$self->{'avg'} = \%avg;
}




sub stddevcheck {
	
	my ( $self ) = @_;
	
	#get my pixel index
	my @pixelindex = @{ $self->{'pixelindex'} };
	
	#get my clut
	my @clut = @{ $self->{'clut'} };
	
	#get my averages
	my %avg = %{ $self->{'avg'} };
	
	#create some storage
	my %stddev;
	$stddev{'red'} = 0;
	$stddev{'green'} = 0;
	$stddev{'blue'} = 0;
	$stddev{'all'} = 0;
	$stddev{'avg'} = 0;
	
	$stddev{'totalred'} = 0;
	$stddev{'totalgreen'} = 0;
	$stddev{'totalblue'} = 0;
	$stddev{'totalall'} = 0;
	$stddev{'totalavg'} = 0;
	
	#for each index entry
	foreach $clutindex ( 1..@pixelindex-1 ) {
		
		#get my colour
		@colour = @{ $clut[$clutindex] };
		
		#add it to each channel as required
		
		#red
		$stddev{'totalred'} += ( ( ( $colour[0] - $avg{'red'} ) ** 2 ) * $pixelindex[$clutindex] );
		
		#green
		$stddev{'totalgreen'} += ( ( ( $colour[1] - $avg{'green'} ) ** 2 ) * $pixelindex[$clutindex] );
		
		#blue
		$stddev{'totalblue'} += ( ( ( $colour[2] - $avg{'blue'} ) ** 2 ) * $pixelindex[$clutindex] );
		
		#all
		$stddev{'totalall'} += ( ( ( $colour[0] - $avg{'red'} ) ** 2 ) * $pixelindex[$clutindex] );
		$stddev{'totalall'} += ( ( ( $colour[0] - $avg{'green'} ) ** 2 ) * $pixelindex[$clutindex] );
		$stddev{'totalall'} += ( ( ( $colour[0] - $avg{'blue'} ) ** 2 ) * $pixelindex[$clutindex] );
		
		#avg
		$stddev{'totalavg'} += ( ( ( ( ( $colour[0] - $avg{'red'} ) ** 2 ) + ( ( $colour[1] - $avg{'green'} ) ** 2 ) + ( ( $colour[2] - $avg{'blue'} ) ** 2 ) ) / 3 ) * $pixelindex[$clutindex] );
		
	}
	
	
	#now get our total pixels
	my $pixelcount = ( $self->{'width'} * $self->{'height'} );
	
	#and close out the averages
	$stddev{'red'} = int( ( $stddev{'totalred'} / ( $pixelcount - 1 ) )  ** 0.5 );
	$stddev{'green'} = int( ( $stddev{'totalgreen'} / ( $pixelcount - 1 ) ) ** 0.5 );
	$stddev{'blue'} = int( ( $stddev{'totalblue'} / ( $pixelcount - 1 ) ) ** 0.5 );
	$stddev{'all'} = int( ( $stddev{'totalall'} / ( ( $pixelcount - 1 ) * 3 ) ) ** 0.5 );
	$stddev{'avg'} = int( ( $stddev{'totalavg'} / ( $pixelcount - 1 ) ) ** 0.5 );
	
	#and now store it
	$self->{'stddev'} = \%stddev;
	
	
	
}















1;